#include "preHeader.h"
#include "MailMgr.h"
#include "GameServer.h"
#include "Game/CharacterMgr.h"
#include "Session/DBPSession.h"

MailMgr::MailMgr()
{
}

MailMgr::~MailMgr()
{
}

WheelTimerMgr *MailMgr::GetWheelTimerMgr()
{
	return &sGameServer.sWheelTimerMgr;
}

void MailMgr::Init()
{
	AcquireMailExpireTime();
}

void MailMgr::AcquireMailExpireTime()
{
	NetPacket rpcReqPck(CDBP_ACQUIRE_MAIL_EXPIRE_TIME);
	sDBPSession.RPCInvoke(rpcReqPck, [=](INetStream& pck, int32 err, bool) {
		if (err == RPCErrorNone && !pck.IsReadableEmpty()) {
			int64 expireTime;
			pck >> expireTime;
			if (expireTime <= GET_UNIX_TIME + ONE_HOUR) {
				CreateTimerX(std::bind(&MailMgr::DeleteMailExpireTime, this),
					SubLeastZero<s64>(expireTime, GET_UNIX_TIME) + ONE_MINUTE, 1);
				return;
			}
		}
		CreateTimerX(std::bind(&MailMgr::AcquireMailExpireTime, this), ONE_HOUR, 1);
	}, &sGameServer);
}

void MailMgr::DeleteMailExpireTime()
{
	NetPacket rpcReqPck(CDBP_CLEAN_EXPIRE_MAIL);
	sDBPSession.RPCInvoke(rpcReqPck, [=](INetStream& pck, int32 err, bool) {
		AcquireMailExpireTime();
	}, &sGameServer);
}

GErrorCode MailMgr::SendMail(const inst_mail& mailProp)
{
	NetBuffer buffer;
	SaveToINetStream(mailProp, buffer);
	return HandleSendSingleMail(buffer);
}

GErrorCode MailMgr::HandleMailRequest(INetStream& pck)
{
	int32 rqstType;
	pck >> rqstType;
	switch (MAIL_RQST_TYPE(rqstType)) {
	case MAIL_RQST_TYPE::SEND_SINGLE:
		return HandleSendSingleMail(pck);
	case MAIL_RQST_TYPE::SEND_MULTI_SAME:
		return HandleSendMultiSameMail(pck);
	case MAIL_RQST_TYPE::SEND_MULTI_DIFFERENT:
		return HandleSendMultiDifferentMail(pck);
	default:
		return InvalidRequest;
	}
}

GErrorCode MailMgr::HandleSendSingleMail(INetStream& pck)
{
	NetPacket rpcReqPck(CDBP_PLAYER_WRITE_MAIL);
	rpcReqPck.Append(pck.GetReadableBuffer(), pck.GetReadableSize());
	sDBPSession.RPCInvoke(rpcReqPck, [=](INetStream& pck, int32 err, bool) {
		if (err == RPCErrorNone) {
			auto pChar = sCharacterMgr.GetCharacter(
				GetGuidFromLowGuid4Player(pck.Read<uint32>()));
			if (pChar != NULL) {
				NetPacket pack(SMSG_MAIL);
				pack << (s32)MAIL_RQST_TYPE::WRITE_ORDER;
				pChar->SendPacket(pack);
			}
		}
	}, &sGameServer);
	return CommonSuccess;
}

GErrorCode MailMgr::HandleSendMultiSameMail(INetStream& pck)
{
	NetPacket rpcReqPck(CDBP_SYSTEM_MULTI_SAME_MAIL);
	rpcReqPck.Append(pck.GetReadableBuffer(), pck.GetReadableSize());
	sDBPSession.RPCInvoke(rpcReqPck, [=](INetStream& pck, int32 err, bool) {
		if (err == RPCErrorNone) {
			while (!pck.IsReadableEmpty()) {
				auto pChar = sCharacterMgr.GetCharacter(
					GetGuidFromLowGuid4Player(pck.Read<uint32>()));
				if (pChar != NULL) {
					NetPacket pack(SMSG_MAIL);
					pack << (s32)MAIL_RQST_TYPE::WRITE_ORDER;
					pChar->SendPacket(pack);
				}
			}
		}
	}, &sGameServer);
	return CommonSuccess;
}

GErrorCode MailMgr::HandleSendMultiDifferentMail(INetStream& pck)
{
	NetPacket rpcReqPck(CDBP_SYSTEM_MULTI_DIFFERENT_MAIL);
	rpcReqPck.Append(pck.GetReadableBuffer(), pck.GetReadableSize());
	sDBPSession.RPCInvoke(rpcReqPck, [=](INetStream& pck, int32 err, bool) {
		if (err == RPCErrorNone) {
			while (!pck.IsReadableEmpty()) {
				auto pChar = sCharacterMgr.GetCharacter(
					GetGuidFromLowGuid4Player(pck.Read<uint32>()));
				if (pChar != NULL) {
					NetPacket pack(SMSG_MAIL);
					pack << (s32)MAIL_RQST_TYPE::WRITE_ORDER;
					pChar->SendPacket(pack);
				}
			}
		}
	}, &sGameServer);
	return CommonSuccess;
}
